﻿using Dapper;
using EFCore.BulkExtensions;
using Furion.DatabaseAccessor;
using Furion.DynamicApiController;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Gear.Web.Tests.DataBase
{
    /// <summary>
    /// EF操作示例
    /// </summary>
    [DynamicApiController]
    [ApiDescriptionSettings("DataOperation")]
    public class EFDemo
    {
        /// <summary>
        /// 注入仓储
        /// </summary>
        private readonly IRepository<DemoEntity> _repository; //必须继承自TEntity

        /// <summary>
        /// 构造函数注入
        /// </summary>
        /// <param name="repository"></param>
        public EFDemo(IRepository<DemoEntity> repository)
        {
            _repository = repository;
        }

        /// <summary>
        /// 参数注入
        /// </summary>
        /// <param name="p_repository">仓储</param>
        /// <returns></returns>
        public DemoEntity ParamInjec([FromServices] IRepository<DemoEntity> p_repository)
        {
            var demo = new DemoEntity { Id = 1, name = "Gear" };
            return p_repository.Insert(demo).Entity;
        }

        /// <summary>
        /// 仓储获取(更多仓储用法请查阅“https://dotnetchina.gitee.io/furion/docs/dbcontext-repository”)
        /// </summary>
        /// <returns>
        /// IRepository：非泛型仓储接口，支持切换到任何仓储
        /// IRepository《TEntity》：泛型仓储,数据库实体仓储接口
        /// IRepository《TEntity，TDbContextLocator》：泛型多数据库实体仓储,数据库实体仓储接口
        /// ISqlRepository：Sql 操作仓储，数据库 Sql 操作仓储接口
        /// ISqlRepository：多数据库 Sql 操作仓储，数据库 Sql 操作仓储接口
        /// </returns>
        public object GetRepository()
        {
            // 非泛型仓储
            var repository = Db.GetRepository();

            // 泛型仓储
            var t_repository = Db.GetRepository<DemoEntity, MasterDbContextLocator>();

            // Sql 仓储
            var sqlRepository = Db.GetSqlRepository<MasterDbContextLocator>();

            return new { repository, t_repository, sqlRepository  };
        }

        #region ==CRUD==

        /// <summary>
        /// 新增方法(更多新增方法请查阅“https://dotnetchina.gitee.io/furion/docs/dbcontext-add”)
        /// </summary>
        /// <returns></returns>
        public DemoEntity Insert()
        {
            var demo = new DemoEntity { Id = 1, name = "Gear" };
            return _repository.Insert(demo).Entity;
        }

        /// <summary>
        /// 更新方法(更多新增方法请查阅“https://dotnetchina.gitee.io/furion/docs/dbcontext-update”)
        /// </summary>
        /// <returns></returns>
        public DemoEntity Update()
        {
            var demo = new DemoEntity { Id = 1, name = "Gear" };
            return _repository.Update(demo).Entity;
        }

        /// <summary>
        /// 删除方法（不推荐物理删除）(更多新增方法请查阅“https://dotnetchina.gitee.io/furion/docs/dbcontext-delete”)
        /// </summary>
        /// <returns></returns>
        public void Delete()=> _repository.Delete(1);

        /// <summary>
        /// 批量新增方法
        /// </summary>
        public void InsertBatch()
        {
            var demoList = new List<DemoEntity>() ;
            demoList.Add(new DemoEntity { Id = 1, name = "Gear" });
            _repository.Context.BulkInsert(demoList);
        }

        /// <summary>
        /// 批量更新方法
        /// </summary>
        public void UpdateBatch()
        {
            var demoList = new List<DemoEntity>();
            demoList.Add(new DemoEntity { Id = 1 });
            _repository.Context.BulkUpdate(demoList);
        }
        /// <summary>
        /// 批量删除方法（不推荐物理删除）
        /// </summary>
        public void DeleteBatch()
        {
            var demoList = new List<DemoEntity>();
            demoList.Add(new DemoEntity { Id = 1 });
            _repository.Context.BulkDelete(demoList);
        }
        /// <summary>
        /// 批量清除数据表（慎用！！！！！）
        /// </summary>
        public void BatchTruncate() => _repository.Context.Truncate<DemoEntity>();
        /// <summary>
        /// 根据条件批量删除（不推荐物理删除）(其他批量操作请查阅“https://dotnetchina.gitee.io/furion/docs/dbcontext-batch#993-efcorebulkextensions-%E4%BD%BF%E7%94%A8”)
        /// </summary>
        /// <returns></returns>
        public int DeleteBatchOpt()=> _repository.Where(a => a.Id > 500).BatchDelete();
        /// <summary>
        /// 根据主键查询（其他根据主键查询方法请查阅“https://dotnetchina.gitee.io/furion/docs/dbcontext-query”）
        /// </summary>
        /// <returns></returns>
        public DemoEntity GetByKey()=> _repository.Find(1);

        /// <summary>
        /// 根据条件查询单条（其他根据条件查询单条方法请查阅“https://dotnetchina.gitee.io/furion/docs/dbcontext-query”）
        /// </summary>
        /// <returns></returns>
        public DemoEntity GetByOpteForOne()=> _repository.Single(u => u.name == "Gear");
        /// <summary>
        /// 查询所有数据（其他查询所有数据方法请查阅“https://dotnetchina.gitee.io/furion/docs/dbcontext-query”）
        /// </summary>
        /// <returns></returns>
        public Task<List<DemoEntity>> GetAll()=>  _repository.AsQueryable().ToListAsync();
        /// <summary>
        /// 根据条件查询所有数据（其他查询所有数据方法请查阅“https://dotnetchina.gitee.io/furion/docs/dbcontext-query”）
        /// </summary>
        /// <returns></returns>
        public Task<List<DemoEntity>> GetAllByOpt()=> _repository.Where(u => u.Id > 10).ToListAsync();
        /// <summary>
        /// 分页查询（其他分页查询方法请查阅“https://dotnetchina.gitee.io/furion/docs/dbcontext-query”）
        /// </summary>
        /// <returns></returns>
        public PagedList<DemoEntity> GetPageList()=> _repository.Where(u => u.Id > 10).ToPagedList(1, 10);

        #endregion
    }

    /// <summary>
    /// SqlSugar操作示例
    /// </summary>
    [DynamicApiController]
    [ApiDescriptionSettings("DataOperation")]
    public class SqlSugarDemo
    {
        /// <summary>
        /// 注入仓储
        /// </summary>
        private readonly ISqlSugarRepository _repository; // 仓储对象：封装简单的CRUD
        private readonly SqlSugarClient _db; // 核心对象：拥有完整的SqlSugar全部功能
        private readonly IAdo _dbAdo;// Ado重载对象 支持原生sql写法

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sqlSugarRepository"></param>
        public SqlSugarDemo(ISqlSugarRepository sqlSugarRepository)
        {
            _repository = sqlSugarRepository;
            _db = _repository.Context;
            _dbAdo = _db.Ado;
        }

        #region ==CRUD==

        /// <summary>
        /// 新增方法（更多新增方法请查阅“https://dotnetchina.gitee.io/furion/docs/sqlsugar”）
        /// </summary>
        /// <returns></returns>
        public int Insert()
        {
            var demo = new DemoEntity { Id = 1, name = "Gear" };
            return _db.Insertable<DemoEntity>(demo).ExecuteCommand();
        }
        /// <summary>
        /// 更新方法（更多更新方法请查阅“https://dotnetchina.gitee.io/furion/docs/sqlsugar”
        /// </summary>
        /// <returns></returns>
        public int Update()
        {
            var demo = new DemoEntity { Id = 1, name = "Gear1" };
            return _db.Updateable<DemoEntity>(demo).ExecuteCommand();
        }
        /// <summary>
        /// 删除方法（不推荐物理删除）（更多删除方法请查阅“https://dotnetchina.gitee.io/furion/docs/sqlsugar”
        /// </summary>
        /// <returns></returns>
        public int Delete()
        {
            var demo = new DemoEntity { Id = 1, name = "Gear1" };
            return _db.Deleteable<DemoEntity>(demo).ExecuteCommand();
        }
        /// <summary>
        /// 根据条件查询所有数据（其他查询所有数据方法请查阅“https://dotnetchina.gitee.io/furion/docs/sqlsugar”）
        /// </summary>
        /// <returns></returns>
        public List<DemoEntity> GetAllByOpt()
        {
            return _dbAdo.SqlQuery<DemoEntity>("select * from demoentity where id=@id and name=@name", new { Id = 1, name = 2 });
        }
        /// <summary>
        /// 分页查询（其他分页查询方法请查阅“https://dotnetchina.gitee.io/furion/docs/sqlsugar”）
        /// </summary>
        /// <returns></returns>
        public List<DemoEntity> GetPageList()
        {
            int total = 0;
            return _db.SqlQueryable<DemoEntity>("select * from demoentity").ToPageList(1, 2, ref total);
        }

        #endregion
    }

    /// <summary>
    /// Dapper操作示例
    /// </summary>
    [DynamicApiController]
    [ApiDescriptionSettings("DataOperation")]

    public class DapperDemo
    {
        /// <summary>
        /// 注入仓储
        /// </summary>
        private readonly IDapperRepository _dapperRepository;
        private readonly IDapperRepository<DemoEntity> _demoRepository;

        /// <summary>
        /// 构造函数注入
        /// </summary>
        /// <param name="dapperRepository"></param>
        /// <param name="demoRepository"></param>

        public DapperDemo(IDapperRepository dapperRepository, IDapperRepository<DemoEntity> demoRepository)
        {
            _dapperRepository = dapperRepository;// dapper仓储
            _demoRepository = demoRepository;// 指定实体仓储
        }

        #region ==CURD==

        /// <summary>
        /// sql执行方法（更多sql执行方法请查阅“https://dotnetchina.gitee.io/furion/docs/dapper”或参考dapper官方仓库“https://github.com/StackExchange/Dapper”）
        /// </summary>
        /// <returns></returns>
        public int SqlExc()
        {
            return _dapperRepository.Execute(@"insert DemoEntity(id, name) values (@a, @b)",
                            new[] { new { Id = 1, name = "Gear" }, new { Id = 2, name = "Gear" }, new { Id = 3, name = "Gear" } });
        }
        /// <summary>
        /// 实体执行方法（更多实体执行方法请查阅“https://dotnetchina.gitee.io/furion/docs/dapper”）
        /// </summary>
        /// <returns></returns>
        public long EntityExc()
        {
            var demo = new DemoEntity { Id = 1, name = "Gear1" };
            return _demoRepository.Insert(demo);

        }
        #endregion
    }
}
